package com.dayuanit.dy15.atm.task;

import com.dayuanit.dy15.atm.entity.Card;
import com.dayuanit.dy15.atm.entity.TransferOrder;
import com.dayuanit.dy15.atm.handler.WebSocketHandler;
import com.dayuanit.dy15.atm.service.CardService;
import com.dayuanit.dy15.atm.service.MessageService;
import com.dayuanit.dy15.atm.util.AtmThreadPool;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import java.util.List;

/**
 * 处理异步转账订单
 * 将钱加入到转入账户
 */
@Component
public class TransferTask extends BaseTask{

    @Autowired
    private WebSocketHandler webSocketHandler;

    @Autowired
    @Qualifier("cardServiceTransferImpl")
    private CardService cardService;

    @Scheduled(cron=" */6  *  *  *  *  ?")
    @Override
    public void process() {
        processTransfer();
    }


    /**
     * 异步处理转账订单
     */
    private void processTransfer() {
        System.out.println(">>>>>>异步转账开始...");

        // 将待转账的订单查出来
        List<TransferOrder> transferOrders = cardService.listTransferOrder4In();

        logger.info(">>>>>>>>>" + cardService.getClass().getName());

        // 循环遍历处理每一笔订单
//        cardService.processTransferIn(transferOrders);//不推荐  这样会将此次所有订单放到一个事务中，如意引起全体失败回滚，造成资源浪费。

        //将循环写在task中，就将事务拆分了，每一个订单都是独立的事务相互木有依赖。就不会出现一个老鼠坏一锅汤。
        for (TransferOrder order : transferOrders) {
            //将每个转账订单提交给线程池运行 提升效率  代码优化
            AtmThreadPool.transferThreadPool.execute(() -> {
                try {
                    //将service方法写在try中，防止某个订单失败，导致其他的订单无法处理。
                    Card cardIn = cardService.processTransferIn(order);
                    logger.info("订单{}转账成功", order.getId());

                    //发送消息给收款方
                    webSocketHandler.sendTransferMessage(order.getAmount(), cardIn.getUserId());
                } catch (Exception e ) {
                    e.printStackTrace();
                    // 将处理失败的订单 修改为转账失败
                    cardService.changeTransferOrder4Fail(order);
                    logger.info("订单{}转账失败", order.getId());
                }
            });
        }

        System.out.println(">>>>>>异步转账结束...");
    }
}
